package cn.lcvc.xnc.authority.config.security.user;

import cn.lcvc.xnc.authority.service.TokenService;
import cn.lcvc.xnc.application.common.model.result.ResponseData;
import cn.lcvc.xnc.application.common.model.result.ResultCode;
import cn.lcvc.xnc.application.common.utils.ResponseUtil;
import cn.lcvc.xnc.application.common.utils.file.Base64FileUtil;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 处理后台管理员登录验证失败的类
 */
@Component
public class UserAuthenticationFailureHandler implements AuthenticationFailureHandler{

    @Autowired
    private Producer producer;//验证码类
    @Autowired
    private TokenService tokenService;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        String message=null;
        if(e instanceof BadCredentialsException){// 密码错误
            message="登录失败：密码错误";
        }else if(e instanceof CredentialsExpiredException){
            message="登录失败：密码已过期";
        }else if(e instanceof LockedException){
            message="登录失败：账户被锁定";
        }else if(e instanceof DisabledException){
            message="登录失败：账户被禁用("+e.getMessage()+")";
        }else if(e instanceof AccountExpiredException){
            message="登录失败：账户已过期";
        }else if(e instanceof InternalAuthenticationServiceException){//经过ljy在2022.2.4调试，账户名不存在使用该异常才能捕获，其他异常不行
            message="登录失败:"+e.getMessage();
        }else{
            message="登录失败（未知异常）："+e.getMessage();
        }
        //ResponseUtil.responseJson(response,ResultCode.UNAUTHORIZED.getCode(),message);
        //20220218将此处错误信息都改为业务异常，不再返回错误的http状态码
        //ResponseUtil.responseJson(response,ResultCode.ERROR.getCode(),message);
        //20220517因为加入了验证码，考虑到安全性，当密码错误时，更新验证码信息，避免穷举破解
        String token=request.getParameter("token");//获取token信息
        //获取验证码生成的文本
        String virifyCode = producer.createText();
        //生成验证码图片
        BufferedImage image = producer.createImage(virifyCode);
        // 将验证码图片转换为base64类型的字符串
        String image64= Base64FileUtil.convertBufferedImageToString(image,"jpg");
        //编写客户端的token存储到redis。
        token = tokenService.getTokenAndSaveVerifyCode(token,virifyCode);
        Map<String,Object> data=new HashMap();
        data.put("token",token);
        data.put("img",image64);
        ResponseUtil.responseJson(response, ResponseData.error(ResultCode.UNAUTHORIZED.getCode(),message,data));
    }
}
